﻿using System;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

using TcpServer;
using UdpServer;

namespace WinForm
{
    static class Program
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        static UDPAsyncServer udpServer;

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Thread thread = new Thread(StartUdpServer);
            thread.Start();
            //Thread.Sleep(1000000);


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormLineChart());
            //Application.Run(new FormAreaChart());
            //Application.Run(new FormLogarithmLineChart());
            //Application.Run(new FormlogarithmAreaChart());
            //Application.Run(new FormDotChart());
            //Application.Run(new FormlogarithmDotChart());
            //Application.Run(new FormPieChart());

            Thread test = new Thread(UdpSendTest);
            test.Start();
        }

        private static TCPHeader CreateHeader()
        {
            return new TestHeader();
        }

        private static void MainHandler(TCPHeader header, TCPBody body)
        {
            //这里一般在header中可能有消息ID。可以在这里进行区分
            TestBody test = (TestBody)body;
            TestHeader testHeader = (TestHeader)header;
            log.Info("我去，这里竟然回调了" + test.testVal1 + "," + test.testVal2);
            log.InfoFormat("回调的MsgId:{0},bodyLen:{1},from:{2}", testHeader.msgId, testHeader.bodyLength + ",", testHeader.RemoteSocket.RemoteEndPoint);
        }

        private static void StartUdpServer()
        {
            Console.WriteLine("StartUdpServer!");
            udpServer = UDPServer.CreateUDPServer("wiker", 4567);
            //下面的事件都是可以用的
            //server.CompletedSend += 发送完成事件
            //server.PrepareSend += 发送数据之前的事件
            //server.NetError += 网络接收错误事件
            //server.OtherException += 其它异常事件
            udpServer.ReceiveBufferSize += 1024;
            int cnt = 0;

            udpServer.DataReceived += (asyncServer, arg) =>
            {
                StrBody strBody = (StrBody)arg.UdpBody;
                cnt++;
                Console.WriteLine("Server 接收：" + strBody.Content + ",CNT=" + cnt);
                asyncServer.Send(arg.State.remote, "Hello client,Server time:" + DateTime.Now);
            };
            udpServer.Start();
            Console.WriteLine("StartUdpServer Over!");
        }


        private static void StartTcpServer()
        {
            Console.WriteLine("StartTcpServer!");
            TCPAsyncServer tcpServer = TCPServer.CreateServer("tcp_server", CreateHeader);
            tcpServer.PrintReceiveHex = true; //开启打印接收到数据的Hex
            tcpServer.PrintSendHex = true; //开启打印发送数据的Hex
            tcpServer.HeaderLength = 8; // 协议中消息头的长度。这个必须设置
            tcpServer.MainNotify += MainHandler; //一个消息接收完之后的事件处理。
            tcpServer.Start(8001);
            Console.WriteLine("StartTcpServer Over!");
        }


        private static void UdpSendTest()
        {
            for (int i = 0; i < 10; i++)
            {
                udpServer.Send(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567), "UdpSendTest");
                Thread.Sleep(10);
            }
            //System.Environment.Exit(0);
        }
    }

    /// <summary>
    /// 消息体，继承Body,接收到消息会自动调用Decode方法，发送时会自动调用Encode方法
    /// </summary>
    public class TestBody : TCPBody
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public int testVal1;
        public string testVal2;

        public override void Debug()
        {
            log.Debug("BODY 打印了DEBUG");
        }

        public override void Info()
        {
            log.Info("BODY 打印了INFO");
        }

        public override void Decode()
        {
            testVal1 = ReadSmallInt();
            testVal2 = ReadStringToEnd();
        }

        //这里不是必须重写，如果重写了，服务器处理完消息后，会将此消息再发送给客户端，
        //也可以手动调用AsyncServer 的Send方法来发送消息
        public override TCPMsg GetSendMsg()
        {
            //构造一个返回的消息
            TestHeader header = new TestHeader();
            header.msgId = 2;
            TestBody body = new TestBody();
            body.testVal1 = 110;
            body.testVal2 = "Hello，" + testVal2;
            TCPMsg msg = new TCPMsg(header, body);
            msg.CloseClient = false;
            return msg;
        }

        public override void Encode()
        {
            WriteBytes(BitConverter.GetBytes(testVal1));
            WriteBytes(Encoding.ASCII.GetBytes(testVal2));
        }
    }


    /// <summary>
    /// 消息头，继承Header,接收到消息会自动调用Decode方法，发送时会自动调用Encode方法
    /// </summary>
    public class TestHeader : TCPHeader
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public int msgId { get; set; }

        public override void Encode()
        {
            WriteBytes(BitConverter.GetBytes(msgId));
            WriteBytes(BitConverter.GetBytes(bodyLength));
        }


        public override void Decode()
        {
            msgId = ReadSmallInt();
            bodyLength = ReadSmallInt();
        }

        public override void Debug()
        {
            log.Debug("Header 打印了DEBUG");
        }

        public override void Info()
        {
            log.Info("Header 打印了INFO");
        }

        /// <summary>
        /// 根据当前的消息头创建一个对应的消息体
        /// </summary>
        /// <returns></returns>
        public override TCPBody InstanceBody()
        {
            return new TestBody();
        }
    }
}
